import { Injectable, Scope, LoggerService as NestLoggerService } from '@nestjs/common';
import pino from 'pino';
import { LoggerFactory } from './logger.factory';

/**
 * Logger 服务
 *
 * 提供 NestJS 依赖注入方式使用 Logger
 * 支持通过 setModule() 动态设置业务模块
 * 实现 NestJS LoggerService 接口，可以接管 NestJS 系统日志
 *
 * @example
 * ```ts
 * @Injectable()
 * export class UserService {
 *   constructor(private readonly logger: LoggerService) {
 *     this.logger.setModule('user');
 *     this.logger.setContext('UserService');
 *   }
 *
 *   async createUser() {
 *     this.logger.info('创建用户');
 *   }
 * }
 * ```
 */
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerService implements NestLoggerService {
  private context?: string;
  private module: string = 'app';
  private logger: pino.Logger;

  constructor() {
    // 默认使用 app 模块的 logger
    this.logger = LoggerFactory.get('LoggerService', this.module);
  }

  /**
   * 设置上下文（类名字符串、类构造函数或对象实例）
   *
   * @example
   * ```ts
   * // 方式 1：传递字符串
   * this.logger.setContext('UserService');
   *
   * // 方式 2：传递类构造函数（推荐）
   * this.logger.setContext(UserService);
   *
   * // 方式 3：传递对象实例
   * this.logger.setContext(this);
   * ```
   */
  setContext(context: string | Function | object): void {
    // 解析上下文名称
    if (typeof context === 'string') {
      this.context = context;
    } else if (typeof context === 'function') {
      this.context = context.name || 'Anonymous';
    } else if (typeof context === 'object' && context !== null) {
      this.context = context.constructor?.name || 'Object';
    } else {
      this.context = 'Unknown';
    }

    this.updateLogger();
  }

  /**
   * 设置业务模块
   */
  setModule(module: string): void {
    this.module = module;
    this.updateLogger();
  }

  /**
   * 获取当前模块
   */
  getModule(): string {
    return this.module;
  }

  /**
   * 更新 logger 实例
   */
  private updateLogger(): void {
    const ctx = this.context || 'LoggerService';
    this.logger = LoggerFactory.get(ctx, this.module);
  }

  /**
   * 记录 trace 级别日志
   */
  trace(message: string): void;
  trace(obj: object, message?: string): void;
  trace(objOrMessage: object | string, message?: string): void {
    if (typeof objOrMessage === 'string') {
      this.logger.trace(objOrMessage);
    } else {
      this.logger.trace(objOrMessage, message);
    }
  }

  /**
   * 记录 debug 级别日志
   */
  debug(message: string): void;
  debug(obj: object, message?: string): void;
  debug(objOrMessage: object | string, message?: string): void {
    if (typeof objOrMessage === 'string') {
      this.logger.debug(objOrMessage);
    } else {
      this.logger.debug(objOrMessage, message);
    }
  }

  /**
   * 记录 info 级别日志
   */
  info(message: string): void;
  info(obj: object, message?: string): void;
  info(objOrMessage: object | string, message?: string): void {
    if (typeof objOrMessage === 'string') {
      this.logger.info(objOrMessage);
    } else {
      this.logger.info(objOrMessage, message);
    }
  }

  /**
   * 记录 warn 级别日志
   */
  warn(message: string): void;
  warn(obj: object, message?: string): void;
  warn(objOrMessage: object | string, message?: string): void {
    if (typeof objOrMessage === 'string') {
      this.logger.warn(objOrMessage);
    } else {
      this.logger.warn(objOrMessage, message);
    }
  }

  /**
   * 记录 error 级别日志
   */
  error(message: string): void;
  error(obj: object, message?: string): void;
  error(objOrMessage: object | string, message?: string): void {
    if (typeof objOrMessage === 'string') {
      this.logger.error(objOrMessage);
    } else {
      this.logger.error(objOrMessage, message);
    }
  }

  /**
   * 记录 fatal 级别日志
   */
  fatal(message: string): void;
  fatal(obj: object, message?: string): void;
  fatal(objOrMessage: object | string, message?: string): void {
    if (typeof objOrMessage === 'string') {
      this.logger.fatal(objOrMessage);
    } else {
      this.logger.fatal(objOrMessage, message);
    }
  }

  /**
   * 记录日志（通用方法，兼容 NestJS LoggerService 接口）
   */
  log(message: string, context?: string): void;
  log(message: any, context?: string): void {
    if (context) {
      this.logger.info({ context }, message);
    } else {
      this.logger.info(message);
    }
  }

  /**
   * 记录 verbose 级别日志（NestJS LoggerService 接口要求）
   * 映射到 debug 级别
   */
  verbose(message: string, context?: string): void;
  verbose(message: any, context?: string): void {
    if (context) {
      this.logger.debug({ context }, message);
    } else {
      this.logger.debug(message);
    }
  }

  /**
   * 获取原始 Pino Logger 实例
   */
  getPinoLogger(): pino.Logger {
    return this.logger;
  }
}

